﻿using Bootstrap.Security.Blazor;
using BootstrapClient.DataAccess.Models;
using BootstrapClient.Web.Core;
using BootstrapClient.Web.Shared.Services;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.CodeAnalysis.Differencing;
using Microsoft.EntityFrameworkCore;
using Microsoft.JSInterop;
using SqlSugar;

namespace BootstrapClient.Web.Shared.Components;
[JSModuleAutoLoader("./_content/BootstrapBlazor/Components/Table/Table.razor.js")]
public class TableEx<TItem> : Table<TItem> where TItem : class, new()
{
    private string storageDataName;

    public TableEx() : base()
    {
        IsBordered = true;
        IsStriped = true;
        IsMultipleSelect = true;
        IsPagination = true;
        PageItemsSource = [10, 20, 50, 100, 1000];
        IsFixedHeader = true;
        //IsTree = false;
        //OnTreeExpand = "OnTreeExpand!";
        //TreeNodeConverter = "TreeNodeConverter!";
        TreeIcon = "fa-chevron-circle-right";
        ShowDefaultButtons = true;
        ShowAdvancedSearch = true;
        ShowEmpty = true;
        EmptyText = "暂无数据";
        EmptyImage = "images/empty.svg";
        //SortString = "@SortString";
        //OnQueryAsync = "OnQueryAsync!";
        //OnDeleteAsync = "OnDeleteAsync!";
        //OnSaveAsync = "OnSaveAsync!";
        ShowSkeleton = true;
        //ShowLoading = false;
        ShowSearch = true;
        ShowToolbar = true;
        ShowExtendButtons = true;

        ShowCardView = true;
        ShowColumnList = true;

        ExtendButtonColumnWidth = 130;
        //CustomerSearchModel = "CustomerSearchModel";
        //SelectedRows = "SelectedRows";
        //ShowExtendEditButtonCallback = "ShowExtendEditButtonCallback!";
        //ShowExtendDeleteButtonCallback = "ShowExtendDeleteButtonCallback!";
        //TableToolbarTemplate = "TableToolbarTemplate";
        //TableColumns = "TableColumns";
        //EditTemplate = "EditTemplate!";
        //CustomerSearchTemplate = "CustomerSearchTemplate!";
        //RowButtonTemplate = "RowButtonTemplate!";
        ShowExportButton = true;
        ShowExportCsvButton = true;
        AutoGenerateColumns = true;
        IsFixedFooter = true;
        AllowResizing = true;
        AllowDragColumn = true;
        //ClientTableName = "@ClientTableName";


        OnDragColumnEndAsync = async (s, e) => await UpdateTableInfoAsync();
        OnResizeColumnAsync = async (s, e) => await UpdateTableInfoAsync();
    }


    [Parameter]
    public string StorageDataName { get => storageDataName; set => storageDataName = base.ClientTableName = $"{value}-{AppContext.UserName}"; }

    [Inject]
    private IJSRuntime? JSRuntime { get; set; }

    [Inject]
    private SqlSugar.ISqlSugarClient db { get; set; }


    protected override void OnInitialized()
    {
        base.OnInitialized();

        ShowAddButton = !AuthorizeButton("add");
        ShowDeleteButton = AuthorizeButton("del");
        ShowEditButton = AuthorizeButton("edit");
    }

    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        _ = SetTableInfoAsync();
    }

    protected override void BuildRenderTree(RenderTreeBuilder __builder)
    {
        base.BuildRenderTree(__builder);
        __builder.OpenElement(1, "script");
        __builder.AddMarkupContent(2, @"
    function reloadColumnOrderEx(tableName) {
        const key = `bb-table-column-order-${tableName}`
        return localStorage.getItem(key);
    }

    function reloadColumnWidthEx(tableName) {
        const key = `bb-table-column-width-${tableName}`
        return localStorage.getItem(key);
    }

    function saveColumnOrderEx(options) {
        const key = `bb-table-column-order-${options.tableName}`
        localStorage.setItem(key, options.data);
    }

    function saveColumnWidthEx(options) {
        const key = `bb-table-column-width-${options.tableName}`
        localStorage.setItem(key, options.data);
    }
");
        __builder.CloseElement();
    }

    private async Task SetTableInfoAsync()
    {
        var ctName = ClientTableName;

        var orders = await JSRuntime.InvokeAsync<string?>("reloadColumnOrderEx", ClientTableName);
        var colwid = await JSRuntime.InvokeAsync<string>("reloadColumnWidthEx", ClientTableName);
        if (orders is null || string.IsNullOrEmpty(colwid))
        {
            var a = db.Queryable<UserLocalStorageData>().Where(t => t.Name == $"bb-table-column-order-{ctName}").Single();
            var b = db.Queryable<UserLocalStorageData>().Where(t => t.Name == $"bb-table-column-width-{ctName}").Single();

            //保存服务器数据
            if (a != null)
            {
                await JSRuntime.InvokeVoidAsync("saveColumnOrderEx", new { tableName = ctName, data = a.Value });
            }
            if (b != null)
            {
                await JSRuntime.InvokeVoidAsync("saveColumnWidthEx", new { tableName = ctName, data = b.Value });
            }
        }
    }

    private async Task UpdateTableInfoAsync()
    {
        var ctName = ClientTableName;
        var orders = await JSRuntime.InvokeAsync<string?>("reloadColumnOrderEx", ClientTableName);
        var colwid = await JSRuntime.InvokeAsync<string>("reloadColumnWidthEx", ClientTableName);

        if (orders != null)
        {
            db.Storageable(new UserLocalStorageData()
            {
                Id = SnowFlakeSingle.Instance.NextId().ToString(),
                Name = $"bb-table-column-order-{ctName}",
                Value = orders
            }).WhereColumns(t => t.Name).ExecuteCommand();
        }
        if (colwid != null)
        {
            db.Storageable(new UserLocalStorageData()
            {
                Id = SnowFlakeSingle.Instance.NextId().ToString(),
                Name = $"bb-table-column-width-{ctName}",
                Value = colwid
            }).WhereColumns(t => t.Name).ExecuteCommand();
        }
    }

    [Inject]
    [NotNull]
    private IBootstrapAdminService? AdminService { get; set; }

    [Inject]
    [NotNull]
    private NavigationManager? NavigationManager { get; set; }

    [Inject]
    [NotNull]
    private BootstrapAppContext? AppContext { get; set; }

    private bool AuthorizeButton(string operate)
    {
        var url = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
        return AdminService.AuthorizingBlock(AppContext.UserName, url, operate);
    }
}
